package com.gitee.apanlh.util.date.parse;

import com.gitee.apanlh.util.date.format.DateTimeFormat;
import com.gitee.apanlh.util.valid.Assert;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;

/**
 * 	时间解析工具类
 * 	
 * 	@author Pan
 */
public class DateParser {
	
	/** 标准时间标记 */
	private static final char NORM_TAG = '-';
	private static final char SECOND_NORM_TAG = '/';
	
	/**
	 * 	构造函数
	 * 	
	 * 	@author Pan
	 */
	private DateParser() {
		//	不允许外部实例
		super();
	}
	
	/***
	 * 	解析时间获取LocalDateTime
	 * 	<br>年月日 时分秒
	 * 	<br>默认解析yyyy-MM-dd HH:mm:ss格式
	 * 	
	 * 	@author Pan
	 * 	@param  time		时间
	 * 	@return LocalDateTime
	 */
	public static LocalDateTime getLocalDateTime(String time) {
		Assert.isNotEmpty(time);
		
		char charAt = time.charAt(4);
		if (charAt == SECOND_NORM_TAG) {
			return getLocalDateTime(time, DateTimeFormat.DATE_TIME_FULL_ALTERNATIVE_SEPARATOR);
		}
		if (Character.isDigit(charAt)) {
			return getLocalDateTime(time, DateTimeFormat.DATE_TIME_NO_SEPARATORS);
		}
		return getLocalDateTime(time, DateTimeFormat.DATE_TIME_FULL);
	}
	
	/***
	 * 	解析时间获取LocalDateTime
	 * 	<br>年月日 时分秒
	 * 	<br>自定义解析格式
	 * 
	 * 	@author Pan
	 * 	@param  time			时间
	 * 	@param  parseFormat		解析时间格式
	 * 	@return LocalDateTime
	 */
	public static LocalDateTime getLocalDateTime(String time, String parseFormat) {
		TemporalAccessor temporalAccessor = parse(time, parseFormat);
		return isSupported(temporalAccessor, ChronoField.NANO_OF_SECOND) ? LocalDateTime.from(temporalAccessor) : null;
	}
	
	/***
	 * 	解析时间获取LocalDate
	 * 	<br>年月日
	 * 	<br>默认解析yyyy-MM-dd格式
	 * 	
	 * 	@author Pan
	 * 	@param  time		时间
	 * 	@return LocalDate
	 */
	public static LocalDate getLocalDate(String time) {
		Assert.isNotEmpty(time);
		
		char charAt = time.charAt(4);
		if (charAt == NORM_TAG) {
			return getLocalDate(time, DateTimeFormat.DATE_FULL);
		}
		if (charAt == SECOND_NORM_TAG) {
			return getLocalDate(time, DateTimeFormat.DATE_FULL_ALTERNATIVE_SEPARATOR);
		}
		if (Character.isDigit(charAt) && time.length() == 8) {
			return getLocalDate(time, DateTimeFormat.DATE_FULL_NO_SEPARATORS);
		}
		return getLocalDate(time,  DateTimeFormat.DATE_FULL);
	}
	
	/***
	 * 	解析时间获取LocalDate
	 * 	<br>年月日
	 * 	<br>自定义解析格式
	 * 	
	 * 	@author Pan
	 * 	@param  time			时间
	 * 	@param  parseFormat		解析时间格式
	 * 	@return LocalDate
	 */
	public static LocalDate getLocalDate(String time, String parseFormat) {
		TemporalAccessor temporalAccessor = parse(time, parseFormat);
		return isSupported(temporalAccessor, ChronoField.EPOCH_DAY) ? LocalDate.from(temporalAccessor) : null;
	}
	
	/***
	 * 	解析时间获取LocalTime
	 * 	<br>时分秒
	 * 	<br>默认解析HH:mm:ss格式
	 * 	
	 * 	@author Pan
	 * 	@param  time		时间
	 * 	@return LocalTime
	 */
	public static LocalTime getLocalTime(String time) {
		return getLocalTime(time, DateTimeFormat.TIME_FULL);
	}
	
	/***
	 * 	解析时间获取LocalTime
	 * 	<br>时分秒
	 * 	<br>自定义解析格式
	 * 	
	 * 	@author Pan
	 * 	@param  time			时间
	 * 	@param  parseFormat		解析时间格式
	 * 	@return LocalTime
	 */
	public static LocalTime getLocalTime(String time, String parseFormat) {
		TemporalAccessor temporalAccessor = parse(time, parseFormat);
		return isSupported(temporalAccessor, ChronoField.SECOND_OF_DAY) ? LocalTime.from(temporalAccessor) : null;
	}
	
	/**
	 * 	是否支持指定字段时间类型
	 * 	
	 * 	@author Pan
	 * 	@param 	temporalAccessor 时间处理器
	 * 	@param 	field	时间字段
	 * 	@return	boolean
	 */
	public static boolean isSupported(TemporalAccessor temporalAccessor, TemporalField field) {
		return temporalAccessor.isSupported(field);
	}
	
	/***
	 * 	解析时间方法
	 * 	
	 * 	@author Pan
	 * 	@param  time			时间
	 * 	@param  parseFormat		解析时间格式
	 * 	@return	TemporalAccessor
	 */
	public static TemporalAccessor parse(String time, String parseFormat) {
		return DateTimeFormat.getFormat(parseFormat).parse(time);
	}
}
